﻿using System.Linq;
using System.Dynamic;
using System.Management.HyperV;

namespace System.Management
{
    internal sealed class DynamicManagementObject : DynamicObject
    {
        private ManagementObject theManagementObject;

        #region Constructor
        public DynamicManagementObject(ManagementObject targetManagementObject)
        {
            this.theManagementObject = targetManagementObject;
        }
        #endregion

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            try
            {
                result = theManagementObject.Properties[binder.Name].Value;
                return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var inParams = theManagementObject.GetMethodParameters(binder.Name);

            int ix = 0;
            foreach (var p in inParams.Properties)
            {
                p.Value = args[ix];
                ix++;
            }

            var invokeResult = theManagementObject.InvokeMethod(binder.Name, inParams, new InvokeMethodOptions() { Timeout = TimeSpan.FromSeconds(1) });

            result = new InvokeResult() { ReturnCode = (ReturnCode)invokeResult["ReturnCode"], Job = (Job)invokeResult["Job"], OutParameters = invokeResult.Properties };

            return true;
        }
    }
}
